/*!
 * @file    	apm32f10x_sdio.h
 *
 * @brief	 	This file contains all the functions prototypes for the ADC firmware library
 *
 * @details	
 *
 * @version		V1.0.0
 *
 * @date    	2019-8-6
 *
 */

#ifndef __APM32F10x_SDIO_H
#define __APM32F10x_SDIO_H

#ifdef __cplusplus
 extern "C" {
#endif
	 
#include "apm32f10x.h"

/**
 * @brief	SDIO Config structure definition
 */
typedef struct
{
	uint32_t ClockEdge;
	uint32_t ClockBypass;
	uint32_t ClockPowerSave;
	uint32_t BusWide;
	uint32_t HardwareFlowControl;
	uint8_t ClockDiv;
}SDIO_ConfigStruct_T;

/**
 * @brief	SDIO CMD Config structure definition
 */
typedef struct
{
	uint32_t Argument;
	uint32_t CmdIndex;
	uint32_t Response;
	uint32_t Wait;
	uint32_t CPSM;
}SDIO_CMD_ConfigStruct_T;

/**
 * @brief	SDIO Data Config structure definition
 */
typedef struct
{
	uint32_t DataTimeOut;
	uint32_t DataLength;
	uint32_t DataBlockSize;
	uint32_t TransferDir;
	uint32_t TransferMode;
	uint32_t DPSM;
}SDIO_DataConfigStruct_T;

/**
 * @brief	SDIO clock edge
 */
typedef enum
{
	SDIO_CLOCK_EDGE_RISING = 0x00000000,
	SDIO_CLOCK_EDGE_FALLING = 0x00002000
}SDIO_CLOCK_EDGE_T;

/**
 * @brief	SDIO clock bypass
 */
typedef enum
{
	SDIO_CLOCK_BYPASS_DISABLE = 0x00000000,
	SDIO_CLOCK_BYPASS_ENABLE = 0x00000400
}SDIO_CLOCK_BYPASS_T;

/**
 * @brief	SDIO clock power save
 */
typedef enum
{
	SDIO_CLOCK_POWER_SAVE_DISABLE = 0x00000000,
	SDIO_CLOCK_POWER_SAVE_ENABLE = 0x00000200
}SDIO_CLOCK_POWER_SAVE_T;

/**
 * @brief	SDIO bus wide
 */
typedef enum
{
	SDIO_BUSWIDE_1B = 0x00000000,
	SDIO_BUSWIDE_4B = 0x00000800,
	SDIO_BUSWIDE_8B = 0x00001000
}SDIO_BUSWIDE_T;

/**
 * @brief	SDIO hardware flow control
 */
typedef enum
{
	SDIO_HARDWARE_FLOW_CONTROL_DISABLE = 0x00000000,
	SDIO_HARDWARE_FLOW_CONTROL_ENABLE = 0x00004000
}SDIO_HARDWARE_FLOW_CONTROL_T;

/**
 * @brief	SDIO power state
 */
typedef enum
{
	SDIO_POWER_STATE_OFF = 0x00000000,
	SDIO_POWER_STATE_ON = 0x00000003
}SDIO_POWER_STATE_T;

/**
 * @brief	SDIO interrupt sources
 */
typedef enum
{
	SDIO_INT_CCRCRAIL = 0x00000001,
	SDIO_INT_DCRCFAIL = 0x00000002,
	SDIO_INT_CTIMEOUT = 0x00000004,
	SDIO_INT_DTIMEOUT = 0x00000008,
	SDIO_INT_TXUNDERR = 0x00000010,
	SDIO_INT_RXOVERR = 0x00000020,
	SDIO_INT_CMDRES = 0x00000040,
	SDIO_INT_CMDSENT = 0x00000080,
	SDIO_INT_DEND = 0x00000100,
	SDIO_INT_STRBITERR = 0x00000200,
	SDIO_INT_DBCKEND = 0x00000400,
	SDIO_INT_CMDACT = 0x00000800,
	SDIO_INT_TXACT = 0x00001000,
	SDIO_INT_RXACT = 0x00002000,
	SDIO_INT_TXFIFOHE = 0x00004000,
	SDIO_INT_RXFIFOHE = 0x00008000,
	SDIO_INT_TXFIFOF = 0x00010000,
	SDIO_INT_RXFIFOF = 0x00020000,
	SDIO_INT_TXFIFOE = 0x00040000,
	SDIO_INT_RXFIFOE = 0x00080000,
	SDIO_INT_TXDAVL = 0x00100000,
	SDIO_INT_RXDAVL = 0x00200000,
	SDIO_INT_SDIOINT = 0x00400000,
	SDIO_INT_CEATAEND = 0x00800000
}SDIO_INT_T;

/**
 * @brief	SDIO response
 */
typedef enum
{
	SDIO_RESPONSE_NO = 0x00000000,
	SDIO_RESPONSE_SHORT = 0x00000040,
	SDIO_RESPONSE_LONG = 0x000000C0
}SDIO_RESPONSE_T;

/**
 * @brief	SDIO wait interrupt state
 */
typedef enum
{
	SDIO_WAIT_NO = 0x00000000,
	SDIO_WAIT_INT = 0x00000100,
	SDIO_WAIT_PEND = 0x00000200
}SDIO_WAIT_T;

/**
 * @brief	SDIO CPSM state
 */
typedef enum
{
	SDIO_CPSM_DISABLE = 0x00000000,
	SDIO_CPSM_ENABLE = 0x00000400
}SDIO_CPSM_T;

/**
 * @brief	SDIO response
 */
typedef enum
{
	SDIO_RES1 = 0x00000000,
	SDIO_RES2 = 0x00000004,
	SDIO_RES3 = 0x00000008,
	SDIO_RES4 = 0x0000000C
}SDIO_RES_T;

/**
 * @brief	SDIO data block size
 */
typedef enum
{
	SDIO_DATA_BLOCKSIZE_1B = 0x00000000,
	SDIO_DATA_BLOCKSIZE_2B = 0x00000010,
	SDIO_DATA_BLOCKSIZE_4B = 0x00000020,
	SDIO_DATA_BLOCKSIZE_8B = 0x00000030,
	SDIO_DATA_BLOCKSIZE_16B = 0x00000040,
	SDIO_DATA_BLOCKSIZE_32B = 0x00000050,
	SDIO_DATA_BLOCKSIZE_64B = 0x00000060,
	SDIO_DATA_BLOCKSIZE_128B = 0x00000070,
	SDIO_DATA_BLOCKSIZE_256B = 0x00000080,
	SDIO_DATA_BLOCKSIZE_512B = 0x00000090,
	SDIO_DATA_BLOCKSIZE_1024B = 0x000000A0,
	SDIO_DATA_BLOCKSIZE_2048B = 0x000000B0,
	SDIO_DATA_BLOCKSIZE_496B = 0x000000C0,
	SDIO_DATA_BLOCKSIZE_8192B = 0x000000D0,
	SDIO_DATA_BLOCKSIZE_16384B = 0x000000E0
}SDIO_DATA_BLOCKSIZE_T;

/**
 * @brief	SDIO transfer direction
 */
typedef enum
{
	SDIO_TRANSFER_DIR_TOCARD = 0x00000000,
	SDIO_TRANSFER_DIR_TOSDIO = 0x00000002
}SDIO_TRANSFER_DIR_T;

/**
 * @brief	SDIO transfer type
 */
typedef enum
{
	SDIO_TRANSFER_MODE_BLOCK = 0x00000000,
	SDIO_TRANSFER_MODE_STREAM = 0x00000004
}SDIO_TRANSFER_MODE_T;

/**
 * @brief	SDIO DPSM state
 */
typedef enum
{
	SDIO_DPSM_DISABLE = 0x00000000,
	SDIO_DPSM_ENABLE = 0x00000001
}SDIO_DPSM_T;

/**
 * @brief	SDIO flag
 */
typedef enum
{
	SDIO_FLAG_CCRCRAIL = 0x00000001,
	SDIO_FLAG_DCRCFAIL = 0x00000002,
	SDIO_FLAG_CTIMEOUT = 0x00000004,
	SDIO_FLAG_DTIMEOUT = 0x00000008,
	SDIO_FLAG_TXUNDERR = 0x00000010,
	SDIO_FLAG_RXOVERR = 0x00000020,
	SDIO_FLAG_CMDRES = 0x00000040,
	SDIO_FLAG_CMDSENT = 0x00000080,
	SDIO_FLAG_DEND = 0x00000100,
	SDIO_FLAG_STRBITERR = 0x00000200,
	SDIO_FLAG_DBCKEND = 0x00000400,
	SDIO_FLAG_CMDACT = 0x00000800,
	SDIO_FLAG_TXACT = 0x00001000,
	SDIO_FLAG_RXACT = 0x00002000,
	SDIO_FLAG_TXFIFOHE = 0x00004000,
	SDIO_FLAG_RXFIFOHE = 0x00008000,
	SDIO_FLAG_TXFIFOF = 0x00010000,
	SDIO_FLAG_RXFIFOF = 0x00020000,
	SDIO_FLAG_TXFIFOE = 0x00040000,
	SDIO_FLAG_RXFIFOE = 0x00080000,
	SDIO_FLAG_TXDAVL = 0x00100000,
	SDIO_FLAG_RXDAVL = 0x00200000,
	SDIO_FLAG_SDIOINT = 0x00400000,
	SDIO_FLAG_CEATAEND = 0x00800000
}SDIO_FLAG_T;

/**
 * @brief	SDIO read wait mode
 */
typedef enum
{
	SDIO_READ_WAIT_MODE_CLK = 0x00000001,
	SDIO_READ_WAIT_MODE_DATA2 = 0x00000000
}SDIO_READ_WAIT_MODE_T;
/* Reset functions **********************************************************/
void SDIO_Reset(void);
/* Configuration functions **********************************************************/
void SDIO_Config(SDIO_ConfigStruct_T* configStruct);
void SDIO_StructInit(SDIO_ConfigStruct_T* configStruct);
void SDIO_Clock_Enable(void);
void SDIO_Clock_Disable(void);
void SDIO_SetPowerState(SDIO_POWER_STATE_T powerState);
uint32_t SDIO_ReadPowerState(void);
/* Interrupt functions **********************************************************/
void SDIO_INT_Enable(SDIO_INT_T interrupt);
void SDIO_INT_Disable(SDIO_INT_T interrupt);
void SDIO_DMA_Enable(void);
void SDIO_DMA_Disable(void);
/* Command functions **********************************************************/
void SDIO_Send_Command(SDIO_CMD_ConfigStruct_T *configStruct);
void SDIO_CmdStructInit(SDIO_CMD_ConfigStruct_T* configStruct);
uint8_t SDIO_ReadCommandResponse(void);
uint32_t SDIO_ReadResponse(SDIO_RES_T response);
void SDIO_DataConfig(SDIO_DataConfigStruct_T* configStruct);
void SDIO_DataStructInit(SDIO_DataConfigStruct_T* configStruct);
/* SDIO data functions **********************************************************/
uint32_t SDIO_ReadDataCounter(void);
uint32_t SDIO_ReadData(void);
uint32_t SDIO_ReadFIFOCount(void);
/* SDIO mode enable or disable functions **********************************************************/
void SDIO_StartReadWait_Enable(void);
void SDIO_StartReadWait_Disable(void);
void SDIO_SetSDIOReadWaitMode(SDIO_READ_WAIT_MODE_T readWaitMode);
void SDIO_IO_Enable(void);
void SDIO_IO_Disable(void);
void SDIO_SendSDIOSuspend_Enable(void);
void SDIO_SendSDIOSuspend_Disable(void);
void SDIO_CommandCompletion_Enable(void);
void SDIO_CommandCompletion_Disable(void);
void SDIO_CEATAINT_Enable(void);
void SDIO_CEATAINT_Disable(void);
void SDIO_SendCEATA_Enable(void);
void SDIO_SendCEATA_Disable(void);
/* Read or clear flag functions **********************************************************/
uint8_t SDIO_ReadFlag(SDIO_FLAG_T flag);
void SDIO_ClearFlag(SDIO_FLAG_T flag);
uint8_t SDIO_ReadINTFlag(SDIO_INT_T interrupt);
void SDIO_ClearITPendingBit(SDIO_INT_T interrupt); 
#ifdef __cplusplus
}
#endif

#endif /* __APM32F10x_SDIO_H */
